<template>
  <!-- 1、进入页面，发请求获取数据进行价格渲染
  2、二维码处理 ---发请求进行二维码付款
  3、轮询支付结果---知道成功弹出提示
  一旦生成二维码就可以询问支付结果
  定时器：只要检测到未支付完成，则隔几秒钟再次询问支付结果，直到支付成功后结束询问（递归）
  4、跳出页面时，在destroyed销毁生命周期，清理定时器
 -->
  <div class="container">
    <div class="main">
      <div class="pay-title">
        支付总金额 <span class="pay-price">￥ {{ payData.price }}</span>
      </div>
      <div class="pay-main">
        <h4>微信支付</h4>
        <el-row
          type="flex"
          justify="space-between"
          align="middle"
          class="pay-qrcode"
        >
          <div class="qrcode">
            <!-- 二维码 -->
            <canvas ref="qrcodeCanvas"></canvas>
            <p>请使用微信扫一扫</p>
            <p>扫描二维码支付</p>
          </div>
          <div class="pay-example">
            <img src="http://157.122.54.189:9093/images/wx-sweep2.jpg" alt="" />
          </div>
        </el-row>
      </div>
    </div>
  </div>
</template>

<script>
import QRcode from "qrcode";
export default {
  data() {
    return {
      payData: {},
      timer: null,
    };
  },
  // 一进入页面就需要发送请求渲染数据，发请求需要打上token，但是此时vuex正在恢复，未恢复前token是不存在的，所以在这个时间段请求数据是会报错的，所以要监听vuex中的token恢复状态，要用watch来监听仓库变化
  watch: {
    // 刷新页面后，没有vuex,需等待恢复，用watch监听vuex数据回来后再次发送请求
    "$store.state.userstore.userInfo.token": {
      handler: function () {
        console.log("触发了");
        console.log(this.$store.state.userstore.userInfo.token);
        if (this.$store.state.userstore.userInfo.token) {
          this.$axios({
            url: "/airorders/" + this.$route.query.id,
            headers: {
              // 请求头传递token  前加 Bearer
              Authorization:
                "Bearer " + this.$store.state.userstore.userInfo.token,
            },
          }).then((res) => {
            console.log(res);
            this.payData = res.data;
            // 根据后台返回来的微信支付url 生成二维码
            // qrcode插件
            // 这个库传入两个参数
            // 1. canvas dom
            // 2. 字符串
            QRcode.toCanvas(
              this.$refs.qrcodeCanvas,
              this.payData.payInfo.code_url,
              {
                width: 200,
                color: {
                  dark: "#00f",
                  light: "#fbb",
                },
              }
            );

            // 一旦生成二维码后询问支付状态---函数封装
            // 首先我们不管轮询逻辑, 只发起一次请求
            this.checkPay();
          });
        }
      },
      // 正常路由页面跳转 vuex存在，可以直接取token 页面一进来直接发送请求获取数据
      immediate: true,
    },
  },
  methods: {
    checkPay() {
      this.$axios({
        method: "post",
        url: "/airorders/checkpay",
        headers: {
          // 请求头传递token  前加 Bearer
          Authorization: "Bearer " + this.$store.state.userstore.userInfo.token,
        },
        data: {
          id: this.payData.id,
          nonce_str: this.payData.price,
          out_trade_no: this.payData.orderNo,
        },
      }).then((res) => {
        console.log(res);
        if (res.data.trade_state !== "SUCCESS") {
          this.timer = setTimeout(() => {
            this.checkPay();
          }, 3000);
        } else {
          this.$message.success("支付完成");
        }
      });
    },
  },
  destroyed() {
    // 销毁组件的时候触发
    // 可以将不能带到别的页面的东西在这里一并销毁即可
    // 这时候页面跳出，需要清理定时器
    // 避免轮询无法停止
    console.log("跳出页面，定时器被清理");
    clearTimeout(this.timer);
  },
};
</script>

<style scoped lang="less">
.container {
  background: #f5f5f5;
  padding: 30px 0;

  .main {
    width: 1000px;
    margin: 0 auto;

    .pay-title {
      text-align: right;
      span {
        font-size: 28px;
        color: orangered;
      }
    }

    .pay-main {
      background: #fff;
      margin-top: 10px;
      border-top: 5px orange solid;
      padding: 30px;

      h4 {
        font-size: 28px;
        font-weight: normal;
        margin-bottom: 10px;
      }

      .pay-qrcode {
        padding: 0 80px;
      }

      .qrcode {
        border: 1px #ddd solid;
        padding: 15px;
        height: fit-content;

        #qrcode-stage {
          width: 200px;
          height: 200px;
          margin-bottom: 10px;
        }

        p {
          line-height: 2;
          text-align: center;
        }
      }
    }
  }
}
</style>